<template>
  <div class="appTemplate">
    <Header :title="'进阶案例-废置对象'" :back="true"/>
    <main ref="threeView" class="main"></main>
    <div class="buttonGroup">
      <button @click="animateClick">{{ animateActive?'停止动画':'启动动画' }}</button>
      <button @click="pointerClick">{{ pointerActive?'停止触控':'启动触控' }}</button>
      <button @click="disposeClick">销毁对象</button>
      <button @click="createClick">创建对象</button>
    </div>
    <Footer />
  </div>
</template>

<script setup lang="ts">
import Header from '@/components/Header.vue';
import Footer from '@/components/Footer.vue';
import {onMounted, ref} from "vue";
// 导入整个 three.js核心库
import * as THREE from 'three';
import Stats from '&t/examples/jsm/libs/stats.module';
// 导入判断WebGL工具
import WebGL from "@/utils/WebGL";
import { ThreeUtil } from "@/utils/ThreeUtil";

THREE.Cache.enabled = true;
// 定义three场景显示区域
const threeView = ref();
const animateActive = ref(true);
const pointerActive = ref(true);
let threeUtil: ThreeUtil;

const animateClick = () => {
  if (animateActive.value) {
    cancelAnimationFrame(threeUtil.animateHandle);
  } else {
    animate();
  }
  animateActive.value = !animateActive.value;
}

const pointerClick = () => {
  // 似乎没有起到作用
  if (pointerActive.value) {
    pointerActive.value = !pointerActive.value;
    threeView.value.removeEventListener( 'pointerdown', onPointerDown );
  } else {
    pointerActive.value = !pointerActive.value;
    threeView.value.addEventListener( 'pointerdown', onPointerDown );
  }
}

const disposeClick = () => {
  threeUtil.scene.remove( threeUtil.items['mesh'] );
  if (animateActive.value === false) {
    randerer();
  }
}

const createClick = () => {
  disposeClick();
  threeUtil.scene.remove( threeUtil.items['mesh'] );
  createImage();
  if (animateActive.value === false) {
    randerer();
  }
}

onMounted(() => {
  if (WebGL.isWebGLAvailable()) {
    initThree();
    animate();
  } else {
    const warning = WebGL.getWebGLErrorMessage();
    threeView.value.appendChild(warning);
  }
})

const initThree = () => {
  threeUtil = new ThreeUtil();
  // 配置相关
  threeUtil.scene.background = new THREE.Color( 0x5a1216 );
  threeUtil.camera.fov = 60;
  threeUtil.camera.near = 1;
  threeUtil.camera.far = 10000;
  threeUtil.camera.position.z = 140;
  threeUtil.renderer.setPixelRatio( window.devicePixelRatio );
  threeUtil.renderer.setSize( threeView.value.offsetWidth, threeView.value.offsetHeight, true );
  createImage();
  randerer();
  threeView.value.appendChild(threeUtil.renderer.domElement);
  threeView.value.style.touchAction = "none";
  threeView.value.addEventListener( 'pointerdown', onPointerDown );
  const stats = new Stats();
  stats.dom.style.position = "absolute";
  threeUtil.items['stats'] = stats;
  threeView.value.appendChild( stats.dom );
}

// 创建canvas图片
const createImage = () => {
  const canvas = document.createElement( 'canvas' );
  canvas.width = threeView.value.offsetWidth / 2;
  canvas.height = threeView.value.offsetHeight / 2;
  const context = canvas.getContext( '2d' );
  if (context) {
    context.fillStyle = 'rgb(' + Math.floor( Math.random() * 256 ) + ',' + Math.floor( Math.random() * 256 ) + ',' + Math.floor( Math.random() * 256 ) + ')';
    context.fillRect( 0, 0, canvas.width -10, canvas.height -10 );
  }
  const geometry = new THREE.SphereGeometry( 50, Math.random() * 64, Math.random() * 32 );
  const texture = new THREE.CanvasTexture( canvas );
  const material = new THREE.MeshBasicMaterial( { map: texture, wireframe: true } );
  const mesh = new THREE.Mesh( geometry, material );
  threeUtil.items['mesh'] = mesh;
  threeUtil.scene.add( threeUtil.items['mesh'] );
}

// 渲染
const randerer = () => {
  threeUtil.renderer.render( threeUtil.scene, threeUtil.camera );
}

const animate = () => {
  threeUtil.animateHandle = requestAnimationFrame( animate );
  randerer();
  threeUtil.items['stats'].update();
}

const onPointerDown = (event: any) => {
  if ( event.isPrimary === false ) return;
  if ( pointerActive.value === false ) return;
  document.addEventListener( 'pointermove', onPointerMove );
  document.addEventListener( 'pointerup', onPointerUp );
}

const onPointerMove = ( event: any ) => {
  if ( event.isPrimary === false ) return;
  const pointerX = event.clientX - (window.innerWidth / 2);
  const pointerY = event.clientY - (window.innerHeight / 2);
  const targetRotationX = pointerX   * 0.02;
  const targetRotationY = pointerY   * 0.02;
  threeUtil.scene.rotation.y += (targetRotationX - threeUtil.scene.rotation.y) * 0.05;
  threeUtil.scene.rotation.x += (targetRotationY - threeUtil.scene.rotation.x) * 0.05;
  threeUtil.renderer.clear();
  threeUtil.renderer.render( threeUtil.scene, threeUtil.camera );
}

const onPointerUp = (event: any) => {
  if ( event.isPrimary === false ) return;
  document.removeEventListener( 'pointermove', onPointerMove );
  document.removeEventListener( 'pointerup', onPointerUp );
}
</script>

<style scoped>

</style>